package org.luxor.commons.core.utils.encrypt;

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import javax.xml.bind.DatatypeConverter;
import java.nio.charset.StandardCharsets;
import java.security.InvalidKeyException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

/**
 * SHA 摘要算法类 <HASH摘要算法>
 *
 * @author Mr.yan @date 2019/10/20
 */
public class ShaEncryptUtils {

    public static String sha1Hex(final String plaintext) {
        return SHA(plaintext, "SHA1");
    }

    public static String sha256Hex(String plaintext) {
        return SHA(plaintext, "SHA-256");
    }

    public static String sha512Hex(String plaintext) {
        return SHA(plaintext, "SHA-512");
    }

    public static String hmac256Hex(String plaintext, String key) {
        byte[] b = hmac256(plaintext, key.getBytes());
        return DatatypeConverter.printHexBinary(b).toLowerCase();
    }

    /**
     * 字符串 SHA 加密方法
     *
     * @param plaintext 明文串
     * @param algorithm SHA-256,SHA-512, SHA1
     * @return 加密串
     */
    private static String SHA(final String plaintext, final String algorithm) {
        MessageDigest md;
        try {
            md = MessageDigest.getInstance(algorithm);
        } catch (NoSuchAlgorithmException e) {
            throw new RuntimeException(algorithm + " is not supported." + e.getMessage());
        }
        byte[] d = md.digest(plaintext.getBytes(StandardCharsets.UTF_8));
        return DatatypeConverter.printHexBinary(d).toLowerCase();
    }

    /**
     * 字符串 hmac256 加密方法
     *
     * @param plaintext 明文串
     * @param key       密钥 KEY
     * @return 密文
     */
    private static byte[] hmac256(String plaintext, byte[] key) {
        Mac mac;
        try {
            mac = Mac.getInstance("HmacSHA256");
        } catch (NoSuchAlgorithmException e) {
            throw new RuntimeException("HmacSHA256 is not supported." + e.getMessage());
        }
        SecretKeySpec secretKeySpec = new SecretKeySpec(key, mac.getAlgorithm());
        try {
            mac.init(secretKeySpec);
        } catch (InvalidKeyException e) {
            throw new RuntimeException(e.getClass().getName() + "-" + e.getMessage());
        }
        return mac.doFinal(plaintext.getBytes(StandardCharsets.UTF_8));
    }

    public static void main(String[] args) {
        String plaintext = "123456";
        System.out.println("sha1Hex:" + sha1Hex(plaintext));
        System.out.println("sha256Hex:" + sha256Hex(plaintext));
        System.out.println("sha512Hex:" + sha512Hex(plaintext));
        System.out.println("hmac256Hex:" + hmac256Hex(plaintext, "luxor@2019"));
    }

}
